package drds.common.db.xml_mapping.parameter_and_result_value_type;

import drds.common.db.xml_mapping.executor.result.ResultMapException;
import drds.common.db.xml_mapping.session.Configuration;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {


  protected Configuration configuration;


  public void setConfiguration(Configuration c) {
    this.configuration = c;
  }

  @Override
  public void setParameter(PreparedStatement preparedStatement, int index, T parameter, JdbcType jdbcType) throws SQLException {
    if (parameter == null) {
      if (jdbcType == null) {
        throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
      }
      try {
        preparedStatement.setNull(index, jdbcType.TYPE_CODE);
      } catch (SQLException e) {
        throw new TypeException("Error setting null for parameter #" + index + " with JdbcType " + jdbcType + " . "
          + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
          + "Cause: " + e, e);
      }
    } else {
      try {
        setNonNullParameter(preparedStatement, index, parameter, jdbcType);
      } catch (Exception e) {
        throw new TypeException("Error setting non null for parameter #" + index + " with JdbcType " + jdbcType + " . "
          + "Try setting a different JdbcType for this parameter or a different configuration property. "
          + "Cause: " + e, e);
      }
    }
  }

  public abstract void setNonNullParameter(PreparedStatement preparedStatement, int index, T parameter, JdbcType jdbcType) throws SQLException;

  @Override
  public T getResult(ResultSet resultSet, String columnName) throws SQLException {
    try {
      return getNullableResult(resultSet, columnName);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e, e);
    }
  }

  public abstract T getNullableResult(ResultSet resultSet, String columnName) throws SQLException;

  @Override
  public T getResult(ResultSet resultSet, int columnIndex) throws SQLException {
    try {
      return getNullableResult(resultSet, columnIndex);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column #" + columnIndex + " from result set.  Cause: " + e, e);
    }
  }

  public abstract T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException;


}
